package proxy;

import org.junit.Test;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * Created by : Infaraway
 * DATE : 2017/3/3
 * Time : 20:07
 * Funtion :
 */
public class DynamicJDKProxy {

    @Test
    public void dynamicJDKProxy(){
        /**
         * ClassLoader :由动态代理产生的对象由那个类加载器来加载 通常情况下和被代理对象使用同样的类加载器
         * Class<?>[] : 由动态代理产生的对象必须要实现的接口的Class数组
         * InvocationHandler : 当具体调用代理对象方法时，将产生什么行为。 通常使用匿名内部类的方式实现
         */
        Calculator calculator = new CalculatorImpl();

        Calculator calculatorProxy = (Calculator) Proxy.newProxyInstance(
                calculator.getClass().getClassLoader(),
                new Class[]{Calculator.class},// 如果代理对象不需要额外实现被代理对象实现的接口以外的接口
                // 可以使用 Calculator.getClass().getInterface()
                new InvocationHandler() {

                    /**
                     * @param proxy 代理
                     * @param method: 正在被调用的方法
                     * @param args ：调用方法时传入的参数
                     * @return 被调用方法的返回值
                     * @throws Throwable
                     */
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        //System.out.println("invoke...");

                        System.out.println("The method "+method.getName()+" begins...");
                        Object obj = method.invoke(calculator, args);
                        System.out.println("The method "+method.getName()+" ends...");

                        return obj;
                    }
                });

        calculatorProxy.mul(2, 3);
        int result = calculatorProxy.add(1, 5);
        System.out.println(result);
    }
}
